package java2020spring;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class Calculator extends JFrame implements ActionListener {
    private final String[] KEYS = { "7", "8", "9", "/", "√", "4", "5", "6",
            "*", "%", "1", "2", "3", "-", "1/x", "0", "±", ".", "+", "=" };
    private final String[] COMMAND = { "Backspace", "CE", "C" };
    private final String[] M = { " ", "MC", "MR", "MS", "M+" };//M键设置参考了网上资料，仍然不是很明白，所以设置上可能有些问题
    private JButton keys[] = new JButton[KEYS.length];
    private JButton commands[] = new JButton[COMMAND.length];
    private JButton m[] = new JButton[M.length];
    private JTextField boxField = new JTextField("0");

    // 标志用户按的是否是整个表达式的第一个数字,或者是运算符后的第一个数字
    private boolean firstDigit = true;
    // 计算的中间结果。
    private double resultNumber = 0.0;
    // 当前运算的运算符
    private String operator = "=";
    // 操作是否合法
    private boolean operateFlag = true;
    //以上变量设置参考网上的一些实现方法进行设置
    
    public Calculator() {
        super();
        init();
        this.setBackground(Color.LIGHT_GRAY); // 设置计算器的背景颜色
        this.setTitle("计算器");
        this.setLocation(500, 300);
        this.setResizable(false);// 不许修改计算器的大小，网上资料
        this.pack();
    }

    private void init() {
        boxField.setHorizontalAlignment(JTextField.RIGHT);
        boxField.setEditable(false);
        boxField.setBackground(Color.white);//颜色设置，网上资料

        JPanel calckeysPanel = new JPanel();
        calckeysPanel.setLayout(new GridLayout(4, 5, 6, 6));
        for (int i = 0; i < KEYS.length; i++) {
            keys[i] = new JButton(KEYS[i]);
            calckeysPanel.add(keys[i]);
            keys[i].setForeground(Color.blue);
            keys[i].setFont(new Font("楷书",Font.PLAIN,20));//设置字体大小,网上资料
        }
        
        // 运算符键用红色标示，其他键用蓝色表示，网上资料
        keys[3].setForeground(Color.red);
        keys[8].setForeground(Color.red);
        keys[13].setForeground(Color.red);
        keys[18].setForeground(Color.red);
        keys[19].setForeground(Color.red);

        JPanel commandsPanel = new JPanel();
        commandsPanel.setLayout(new GridLayout(1, 3, 6, 6));
        for (int i = 0; i < COMMAND.length; i++) {
            commands[i] = new JButton(COMMAND[i]);
            commandsPanel.add(commands[i]);
            commands[i].setForeground(Color.red);
            commands[i].setFont(new Font("楷书",Font.PLAIN,20));//设置字体大小,网上资料
        }
        JPanel calmsPanel = new JPanel();
        calmsPanel.setLayout(new GridLayout(5, 1, 6, 6));
        for (int i = 0; i < M.length; i++) {
            m[i] = new JButton(M[i]);
            calmsPanel.add(m[i]);
            m[i].setForeground(Color.red);
        }
        JPanel panel1 = new JPanel();
        panel1.setLayout(new BorderLayout(6, 6));
        panel1.add("North", commandsPanel);
        commandsPanel.setPreferredSize(new Dimension(0, 100));
        panel1.add("Center", calckeysPanel);
        JPanel top = new JPanel();
        top.setLayout(new BorderLayout());
        top.add("Center", boxField);
        top.setPreferredSize(new Dimension(0, 200));
        //设置区域大小，网上资料
        boxField.setFont(new Font("楷书",Font.PLAIN,30));
        //设置文本框内字体大小，网上资料
        getContentPane().setLayout(new BorderLayout(3, 5));
        getContentPane().add("North", top);
        getContentPane().add("Center", panel1);
        getContentPane().add("West", calmsPanel);
        for (int i = 0; i < KEYS.length; i++) {
            keys[i].addActionListener(this);
        }
        for (int i = 0; i < COMMAND.length; i++) {
            commands[i].addActionListener(this);
        }
        for (int i = 0; i < M.length; i++) {
            m[i].addActionListener(this);
        }
    }

    public void actionPerformed(ActionEvent e) {
        String label = e.getActionCommand();
        if (label.equals(COMMAND[0])) {
            handleBackspace();
        } 
        else if (label.equals(COMMAND[1])) {
            boxField.setText("0");
        }
        else if (label.equals(COMMAND[2])) {
            handleC();
        }
        else if ("0123456789.".indexOf(label) >= 0) {
            handleNumber(label);
        } 
        else {
            handleOperator(label);
        }
    }

    private void handleBackspace() {
        String text = boxField.getText();
        int i = text.length();
        if (i > 0) {
            // 退格，将文本最后一个字符去掉
            text = text.substring(0, i - 1);
            if (text.length() == 0) {
                boxField.setText("0");
                firstDigit = true;
                operator = "=";
            } else {
                boxField.setText(text);
            }
        }
    }

    private void handleNumber(String key) {
        if (firstDigit) {
            boxField.setText(key);
        }
        else if ((key.equals(".")) && (boxField.getText().indexOf(".") < 0)) {
            boxField.setText(boxField.getText() + ".");
        }
        else if (!key.equals(".")) {
            boxField.setText(boxField.getText() + key);
        }
        firstDigit = false;
    }

    private void handleC() {
        boxField.setText("0");
        firstDigit = true;
        operator = "=";
    }

    private void handleOperator(String key) {
        if (operator.equals("/")) {
            if (getNumberFromText() == 0.0) {
                operateFlag = false;
                boxField.setText("除数不能为零");
            } else {
                resultNumber /= getNumberFromText();
            }
        }
        else if (operator.equals("1/x")) {
            if (resultNumber == 0.0) {
                operateFlag = false;
                boxField.setText("零没有倒数");
            }
            else {
                resultNumber = 1 / resultNumber;
            }
        }
        else if (operator.equals("+")) {
            resultNumber += getNumberFromText();
        }
        else if (operator.equals("-")) {
            resultNumber -= getNumberFromText();
        }
        else if (operator.equals("*")) {
            resultNumber *= getNumberFromText();
        }
        else if (operator.equals("√")) {
            resultNumber = Math.sqrt(resultNumber);
        }
        else if (operator.equals("%")) {
            resultNumber = resultNumber / 100;
        }
        else if (operator.equals("±")) {
            resultNumber = resultNumber * (-1);
        }
        else if (operator.equals("=")) {
            resultNumber = getNumberFromText();
        }
        if (operateFlag) {
            // 双精度浮点数的运算，网上资料
            long numberOne;
            double numberTwo;
            numberOne = (long) resultNumber;
            numberTwo = resultNumber - numberOne;
            if (numberTwo == 0) {
                boxField.setText(String.valueOf(numberOne));
            } else {
                boxField.setText(String.valueOf(resultNumber));
            }
        }
        // 运算符等于用户按的按钮
        operator = key;
        firstDigit = true;
        operateFlag = true;
    }
    /*计算，按一次符号后，若再按一次不是等于号的符号
     * 时，先计算出结果，再继续下一步操作，参考网上方法
    */
    private double getNumberFromText() {
        double result = 0;
        try {
            result = Double.valueOf(boxField.getText()).doubleValue(); 
        } catch (NumberFormatException e) {
        }
        return result;
    }//获取文本框的数字，网上资料//

    public static void main(String args[]) {
        Calculator calculator1 = new Calculator();
        calculator1.setBounds(100,100,600,800);
        calculator1.setVisible(true);
        calculator1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}